// mainstatic
package main

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"
)

//key
var CLIENT_KEY = ""

type MainStatic struct {
	CLIENT_ID          string           //本身IP
	CHECK_RESTART      bool             //是否要重启
	ZK_WATCH_PATH      string           //zk监控路径
	ETCD_ZK_MASTER     *EtcdAndZkMaster //ETCD与zk处理对像
	ETCD_HV_WATCH_PATH string           //etcd高可用/分布式监控路径
	ZK_HV_WATCH_PATH   string           //ZK高可用监控路径
	SYS_CONFIG         *SysConfig       //配制文件
	CLIENT_LEADER      *ClientLeader    //领导对像
}

//
func NewMainStatic() *MainStatic {
	return &MainStatic{CHECK_RESTART: false, ETCD_HV_WATCH_PATH: "/dockerregister", ZK_HV_WATCH_PATH: "/dockerregister"}
}

//初始化资源
func InitResourceMain() *MainStatic {
	if mainStatic != nil {
		mainStatic.CloseResourceMain()
		//等待10秒
		time.Sleep(time.Second * 10)
	}
	mainStatic = nil

	//每重启一次生成新的clientkey
	CLIENT_KEY = GetUtilClientKey()

	ms := NewMainStatic()

	mainStatic = ms

	sysConfig := NewSysconfig()
	ms.SYS_CONFIG = sysConfig

	ms.ZK_WATCH_PATH = sysConfig.zkWatchPath //"/alogic/global/arm"
	var etcdAndZkMaster = NewEtcdAndZkMaster()
	ms.ETCD_ZK_MASTER = etcdAndZkMaster
	//etcd  pod容器监控
	var etcdMaster = NewEtcdMaster(sysConfig.etcdAddress)
	//zk监控
	var zkMaster = NewZkMaster(sysConfig.zkAddress)
	etcdAndZkMaster.SetEtcdMaster(etcdMaster)
	etcdAndZkMaster.SetZkMaster(zkMaster)
	//自身服务注册到ZK,
	ok, _, _ := zkMaster.zkConnect.Exists(ms.ZK_HV_WATCH_PATH)
	if ok == false {
		zkMaster.CreateZkPath(ms.ZK_HV_WATCH_PATH)
	}
	ok, _, _ = zkMaster.zkConnect.Exists(ms.ZK_HV_WATCH_PATH + "/client")
	if ok == false {
		zkMaster.CreateZkPath(ms.ZK_HV_WATCH_PATH + "/client")
	}

	ok, _, _ = zkMaster.zkConnect.Exists(ms.ZK_HV_WATCH_PATH + "/client/" + CLIENT_KEY)
	if ok == true {
		zkMaster.DeleteZkSessionPath(ms.ZK_HV_WATCH_PATH + "/client/" + CLIENT_KEY)
	}
	zkMaster.CreateZkSessionClientKey(ms.ZK_HV_WATCH_PATH + "/client/" + CLIENT_KEY)
	//etcd建自己的监控目录
	// .Get(context.Background(), mainStatic.ETCD_HV_WATCH_PATH+"/"+clientId+"/", nil)
	member := &Member{AppName: "0", ClientId: CLIENT_KEY, IP: "0.0.0.0", Port: "0"}
	etcdMaster.AddEtcdHvInfo(member)
	etcdMaster.DeleteEtcdMemberPath(member)
	return ms
}

//监听资源
func (ms *MainStatic) WatchResource() {
	//监听本身client的目录
	go ms.ETCD_ZK_MASTER.etcdMaster.WatchHvWokers()
	for {
		if mainStatic.CHECK_RESTART == true {
			return
		}
		var isLeader = ms.CheckMainMachine()

		if ms.CLIENT_LEADER == nil && isLeader == true {
			ms.CLIENT_LEADER = NewClientLeader(ms.ETCD_ZK_MASTER)
			ms.CLIENT_LEADER.InitLeader()
			go ms.CLIENT_LEADER.HeartLeaderModule()
			go ms.ETCD_ZK_MASTER.etcdMaster.WatchWorkers()

		} else if ms.CLIENT_LEADER != nil && isLeader == false { //提高性能，没有使用分布锁,极端情况出现两个leader
			fmt.Println("############发现伪主机，重新分配####################")
			mainStatic.CHECK_RESTART = true

		}

		time.Sleep(time.Second * 5)

	}

	//
	//ms.ETCD_ZK_MASTER.etcdMaster.InitPodWorker()
	//监听etcd的变化

}

//检查是否为主机器
func (ms *MainStatic) CheckMainMachine() bool {

	ok, _, _ := ms.ETCD_ZK_MASTER.zkMaster.zkConnect.Exists(ms.ZK_HV_WATCH_PATH + "/leader")

	if ok == false {
		ms.ETCD_ZK_MASTER.zkMaster.CreateZkPath(ms.ZK_HV_WATCH_PATH + "/leader")
	}

	cli, _, _err := ms.ETCD_ZK_MASTER.zkMaster.zkConnect.Children(ms.ZK_HV_WATCH_PATH + "/leader")

	if _err != nil {
		fmt.Print("=========(1)=========================")
		mainStatic.CHECK_RESTART = true
		return false
	}
	//客户端
	cli001, _, err := ms.ETCD_ZK_MASTER.zkMaster.zkConnect.Children(ms.ZK_HV_WATCH_PATH + "/client")
	if err != nil {
		fmt.Print("=========(2)=========================")
		mainStatic.CHECK_RESTART = true
		return false
	}
	//
	if len(cli) > 0 {
		if cli[0] == CLIENT_KEY {
			return true
		}
		return false
	}
	//对客户端排序
	clientSort := make([]*ClientSort, len(cli001))

	for i := 0; i < len(cli001); i++ {

		cs := strings.Split(cli001[i], "-")
		val, _ := strconv.Atoi(cs[1])
		clientSort[i] = &ClientSort{cli001[i], val}
	}
	pList := ClientSortList(clientSort)
	sort.Sort(pList)
	if pList[0].clientId == CLIENT_KEY {
		fmt.Println("\n ######################主机器为：[" + CLIENT_KEY + "] ##########\n")
		ms.ETCD_ZK_MASTER.zkMaster.CreateZkSessionPath(ms.ZK_HV_WATCH_PATH + "/leader/" + CLIENT_KEY)
		return true
	}

	return false
}

//回收资源
func (ms *MainStatic) CloseResourceMain() {

	if ms != nil && ms.ETCD_ZK_MASTER != nil && ms.ETCD_ZK_MASTER.zkMaster != nil && ms.ETCD_ZK_MASTER.zkMaster.zkConnect != nil {
		ms.ETCD_ZK_MASTER.zkMaster.zkConnect.Close()
	}

	if ms != nil && ms.ETCD_ZK_MASTER != nil {
		ms.ETCD_ZK_MASTER.Close()
	}

	if ms != nil && ms.SYS_CONFIG != nil {
		ms.SYS_CONFIG = nil
	}
	if ms != nil && ms.CLIENT_LEADER != nil {
		ms.CLIENT_LEADER = nil
	}

	ms = nil
}
